PHP设计模式-工厂

“one day~ ”

瞎BB

Ziv 的 Blog 就这么开通了。

2016 年末,Ziv 总算有个地方可以随便写点东西了。

一直想找个地方,把自己看到的学到的东西都写写。Blog 这个东西一直惦记好久了。最近才发现了githup + jekyll 这地方。本来准备用HEXO的。后来觉得jekyll 的模板好看。我就又用这个了。花了漫长的时间去弄的。本来在WIN上玩Ruby 就不是太舒服。后来自己搭了个虚拟机Ubuntu。才觉得顺手了。

一直觉得自己技术不是很扎实,所以最近一直在补PHP基础。所以就刚好随便写写。


适用性

工厂设计模式提供获取某个对象的新实例的一个接口,同时使调用代码避免确定实际实例化基类的步骤。

UML

代码示例

为了管理控制CD,应用程序需要将必要的信息编辑入CD 对象。然后传递出去。完成CD创建工作。CD 对象需要包含标题,乐队名称,曲目列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class cd
{
public $title = '';
public $band = '';
public $track = array();

public function __construct()
{

}

public function setTitle($title)
{
$this->title = $title;
}

public function setBand($band)
{
$this->band = $band;
}

public function addTrack($track)
{
$this->track[] = $track;
}

}

为了创建完整的CD对象。处理过程相同: 创建一个CD类的实例,然后添加标题,乐队名称,曲目列表。

1
2
3
4
5
6
7
8
9
10
$title = 'Waste of a Rib';
$band = 'Never Again';
$tracksFromExternalSoutce = array('What It Means','Brrr','Goodbye');

$cd = new CD();
$cd->setTitle($title);
$cd->setBand($band);
foreach ($tracksFromExternalSoutce as $track ){
$cd->addTrack($track);
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
object(cd)#1 (3) {
["title"]=>
string(14) "Waste of a Rib"
["band"]=>
string(11) "Never Again"
["track"]=>
array(3) {
[0]=>
string(13) "What It Means"
[1]=>
string(4) "Brrr"
[2]=>
string(7) "Goodbye"
}
}

如今,某些艺术家在他们的CD上发布了在计算机中能够使用的其他内容。这些CD称为增强型CD。写至光盘的第一个音轨是数据音轨。管理控制软件通过其他标签DATA TRACK识别数据音轨,并且创建相应的CD对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class enhancedCD
{
public $title = '';
public $band = '';
public $track = array();

public function __construct()
{
$this->track[] = 'DATA TRACK';
}

public function setTitle($title)
{
$this->title = $title;
}

public function setBand($band)
{
$this->band = $band;
}

public function addTrack($track)
{
$this->track[] = $track;
}
}

查看上述共性和认识到只可能存在两种CD类型之后,似乎我们只需要创造条件语句。如果CD类型是增强型CD,那么就创建enhancedCD类的实例。否则,就应创建通用CD类。然而更好的解决方案:使用工厂设计模式。
CDFactory类使用了PHP根据比变量动态实例化一个类的能力。create()方法接受被请求类的类型并返回类的一个实例:

1
2
3
4
5
6
7
8
9
class CDFactry
{
public static function create($type)
{
$class = strtolower($type).'CD';

return new $class;
}
}

现在,类的创建和执行变化反应了Factory 类的用法:

1
2
3
4
5
6
7
$type = 'enhanced';
$cd = CDFactry::create($type);
$cd->setBand($band);
$cd->setTitle($title);
foreach ($tracksFromExternalSoutce as $track ){
$cd->addTrack($track);
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
object(enhancedCD)#2 (3) {
["title"]=>
string(14) "Waste of a Rib"
["band"]=>
string(11) "Never Again"
["track"]=>
array(4) {
[0]=>
string(10) "DATA TRACK"
[1]=>
string(13) "What It Means"
[2]=>
string(4) "Brrr"
[3]=>
string(7) "Goodbye"
}
}